﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace AutoWordInfo
{

    public struct ActicleInfo
    {
        public string filename;   //word文件名
        public long id;           //id
        public int pageNum;       //页数
        public int wordCount;     //字数
        public string paperCode;  //证券代码
        public string paperName;  //证券简称
        public string paperNumber;//证券编号
        public int tableWordNum;      //表格数量
        public int pictureNum;    //表格数量
        public int rowNum;        //表格行数
        public string property;   //公告属性  董事会 、监事会、股东大会
        public string priviewUrl; //word生成的url，方便定稿使用
        public void init()
        {
            filename = "";
            id = 0;
            pageNum = 0;
            wordCount = 0;
            paperCode = "";
            paperName = "";
            paperNumber = "";
            tableWordNum = 0;
            pictureNum = 0;
            rowNum = 0;
            property = "";
            priviewUrl = "";
        }

    }



    public partial class Form1 : Form
    {

      
        private bool start = false;   //监控线程开启标志
        private int threadNumber = 0;       //线程最大个数是5个
        private string wordProperty = "";
        ConcurrentQueue<KeyValuePair<long, string>> wordQueue = new ConcurrentQueue<KeyValuePair<long, string>>(); //监控数据库中合并word数据队列

        private delegate void setRichTextDelegate(string str);
        private Thread[] threads = null;
        private Thread listenthread = null;
        //ini文件读写操作
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        public Form1()
        {
            InitializeComponent();
            LoadFromIni();
        }
        private void LoadFromIni()
        {
            string m_strINIpath = Path.GetDirectoryName(Application.ExecutablePath) + @"\setting.ini";

            StringBuilder strBdRetn = new StringBuilder();
            GetPrivateProfileString("Common", "ThreadNum", "2", strBdRetn, 255, m_strINIpath);   //默认为2个线程
            threadNumber = int.Parse(strBdRetn.ToString());

        }
        

        public void checkConnect()
        {
            MysqlServer my = new MysqlServer();
            int result = my.checkConnect();
            string mess = string.Format(@"{0}:数据库已连接成功 ***************", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            if (result != 1)
            {
                mess = string.Format(@"{0}:数据库未连上,请配置参数后使用*************", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            }
            setRichText(mess);
        }



        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void 启动toolStripButton_Click(object sender, EventArgs e)
        {
            startListen(true);
        }

        private void 停止toolStripButton_Click(object sender, EventArgs e)
        {
            startListen(false);
        }



        public bool startListen(bool open)
        {
            try
            {
                //启动或者停止的时候关闭word、wps进程
                foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("WINWORD"))
                {
                    p.Kill();
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
                foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("wps"))
                {
                    p.Kill();
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
                start = open;
                if (threads == null)
                {
                    listenthread = new Thread(new ThreadStart(ListenThread));
                    listenthread.Start();

                    threads = new Thread[threadNumber];
                    for (int i = 0; i < threadNumber; i++)
                    {
                        threads[i] = new Thread(new ThreadStart(readThread));
                        threads[i].Name = i.ToString();
                        threads[i].SetApartmentState(ApartmentState.STA);
                        threads[i].Start();
                    }
                }
                if (!start)  //点击停止
                {
                    resetWordState();
                }
            }
            catch (System.Exception ex)
            {

            }

            return false;
        }


        /// <summary>
        /// 监听数据线程
        /// </summary>
        private void ListenThread()
        {
            while(true)
            {
                if(start)
                {
                    MysqlServer mysql = new MysqlServer();
                    Dictionary<long, string> list = mysql.getWordInfo();
                    foreach (KeyValuePair<long, string> kvp in list)
                    {
                        wordQueue.Enqueue(kvp);
                    }
                    if (list != null && list.Count == 0)
                    {
                        string mess = string.Format("{0}:查询到没有待读取的数据", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        setRichText(mess);
                    }
                }
                Thread.Sleep(10000);
            }


        }


        private void getWordProperty()
        {
            MysqlServer mysql = new MysqlServer();
            string strproperty = mysql.getProperty();
            wordProperty = strproperty;
        }

        /// <summary>
        /// 读取内容线程
        /// </summary>
        private void readThread()
        {
            while(true)
            {
                if(start)
                {
                    try
                    {
                        ActicleInfo info = new ActicleInfo(); ;
                        info.init();
                        KeyValuePair<long, string> kvp;
                        MysqlServer mysql = new MysqlServer();
                        GetWordInfo.ReadWord read = new GetWordInfo.ReadWord();
                        int state =0;
                        bool ret;
                        lock (wordQueue)
                        {
                            ret = wordQueue.TryDequeue(out kvp);
                        }
                        if(ret)
                        {
                            string filepath = kvp.Value;
                            info.id = kvp.Key;
                            string threadName = Thread.CurrentThread.Name;   //当前线程名称
                            string mess = string.Format("线程{0}启动--{1} 开始读取 :{2}", threadName, kvp.Value, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            setRichText(mess);
                            mess = string.Format("线程{0}---{1} 读取完成: {2}  \r\n", threadName, filepath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            state = read.getWordInfoByName(filepath, wordProperty);
                            if(state != 1)
                            {
                                mess = string.Format("线程{0}---{1} 读取异常: {2}  \r\n", threadName, filepath, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                            }
                            setRichText(mess);

                            info.id = kvp.Key;
                            info.filename = kvp.Value;
                            info.pageNum = read.info.pageNum;
                            info.paperCode = read.info.paperCode;
                            info.paperName = read.info.paperName;
                            info.paperNumber = read.info.paperNumber;
                            info.pictureNum = read.info.pictureNum;
                            info.property = read.info.property;
                            info.rowNum = read.info.rowNum;
                            info.tableWordNum = read.info.tableWordNum;
                            info.wordCount = read.info.wordCount;
                            info.priviewUrl = read.info.priviewUrl;
                            mysql.updateFileInfo(info);
                        }
                    }
                    catch(Exception ex)
                    {


                    }
                }
                Thread.Sleep(100);
            }
        }

        private bool resetWordState()
        {

            KeyValuePair<long, string> kvp;
            //不为空，意味着队列中还有未合并的文档，此时要对未合并的文档进行处理
            int count = 0;
            try
            {
                foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("WINWORD"))
                {
                    p.Kill();
                }
                GC.Collect();
                GC.WaitForPendingFinalizers();
                while (wordQueue.TryDequeue(out kvp))
                {
                    count++;
                }
                MysqlServer mysql = new MysqlServer();
                mysql.resetState();   //重置任务
                string mess = string.Format(@"{0}:服务已经停止*************************************", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                setRichText(mess);
            }
            catch(Exception ex)
            {

            }
         
            return true;
        }




        public bool closeThread()
        {

            if (threads != null)
            {
                for (int i = 0; i < threadNumber; i++)
                {
                    threads[i].Abort();
                }
                threads = null;
            }
            if (listenthread != null)
            {
                listenthread.Abort();
                listenthread = null;
            }
            GC.Collect();
            return true;
        }


        //define a method which match the above delegae
        private void setRichText(string str)
        {
            // query the control's(here is lstResults) InvokeRequired
            if (this.richTextBox1.InvokeRequired)
            {
                //instansiate a delegate with the method
                setRichTextDelegate myDelegate = new setRichTextDelegate(setRichText);
                //Invoke delegate
                this.richTextBox1.Invoke(myDelegate, str);
            }
            else
            {
                //InvokedRequired is false, so call the control directly
                this.richTextBox1.Text = str + "\r\n" + this.richTextBox1.Text;
            }
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            closeThread();
        }

        private void 参数设置ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Setting set = new Setting();
            set.ShowDialog();
        }
    }
}
